﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Microsoft.DataTransformationServices.Controls;
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Runtime.Design;
using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
using ConnectionManager = Microsoft.SqlServer.Dts.Runtime.ConnectionManager;

namespace Bewise.SmartIndexManagerLT.UI.UserControls
{
    public partial class Uc_MainConfiguration : UserControl, IDTSTaskUIView
    {
        private SmartIndexManagerLT_IHM _indexManager;
        private IDtsConnectionService _connectionsAdodotnet;
        private string _connectionManagerName;
        private ConnectionManager _connectionManager;

        public Uc_MainConfiguration()
        {
            InitializeComponent();
            comboBoxConnections.SelectedIndexChanged += ComboBoxConnectionsSelectedIndexChanged;
        }

        public void OnInitialize(IDTSTaskUIHost treeHost, TreeNode viewNode, object taskHost, object connections)
        {
            // récupération des ConnectionManagers
            _connectionsAdodotnet = connections as IDtsConnectionService;

            if (taskHost != null)
                if (taskHost is TaskHost)
                {
                    // récupération d'une référence vers notre Task via InnerObject
                    _indexManager = ((TaskHost)taskHost).InnerObject as SmartIndexManagerLT_IHM;
                    if (_indexManager != null)
                    {
                        if (_connectionsAdodotnet != null)
                        {
                            // bind ComboConnections
                            InitComboBoxConnections();

                            // bind Initial Catalog
                            // récupération du connectionManager courant
                            _connectionManager = GetConnectioManager(_connectionsAdodotnet.GetConnections(), _connectionManagerName);
                            if (_connectionManager != null)
                            {
                                // récupération de toutes les bases de données
                                // associées au ConnectionManager _connectionManager
                                InitComboInitialCatalog(_connectionManager);
                            }

                            // initialize textBoxQuery
                            if (!string.IsNullOrEmpty(_indexManager.Query))
                                textBoxQuery.Text = _indexManager.Query;
                        }
                    }
                }
        }

        public void OnValidate(ref bool bViewIsValid, ref string reason)
        {

        }

        public void OnSelection()
        {

        }

        public void OnLoseSelection(ref bool bCanLeaveView, ref string reason)
        {

        }

        public void OnCommit(object taskHost)
        {
            // récupération la connection dans SqlServerConnection
            if (comboBoxConnections.SelectedItem != null)
                _indexManager.SqlServerConnection = comboBoxConnections.SelectedItem.ToString();

            // récupération de la base de données InitialCatalog
            if (comboBoxInitialCatalog.SelectedItem != null)
                _indexManager.InitialCatalog = comboBoxInitialCatalog.SelectedItem.ToString();

            // récupération de la Query saisie
            if (!string.IsNullOrEmpty(textBoxQuery.Text))
                _indexManager.Query = textBoxQuery.Text;
        }

        private void InitComboBoxConnections()
        {
            // récupération des ConnectionManagers associés à ADO.NET
            var listAdonetcm = GetListADO_NETProviders(_connectionsAdodotnet.GetConnections());

            // stockage des ConnectionManagers dans la combo comboBoxConnections
            foreach (var item in listAdonetcm)
                comboBoxConnections.Items.Add(item);

            // Affichage dans la combo comboBoxConnections de l'item SqlServerConnection
            _connectionManagerName = _indexManager.SqlServerConnection;
            if (listAdonetcm.IndexOf(_connectionManagerName) != -1)
                comboBoxConnections.SelectedItem = _connectionManagerName;
        }

        private void InitComboInitialCatalog(ConnectionManager currentConnectionManager)
        {
            SqlConnection conn = new SqlConnection(currentConnectionManager.ConnectionString);
            ServerConnection serverConnection = new ServerConnection(conn);
            Server server = new Server(serverConnection);

            try
            {
                comboBoxInitialCatalog.Items.Clear();

                // récupération de toutes les base de données de currentConnectionManager
                foreach (Database database in server.Databases)
                    comboBoxInitialCatalog.Items.Add(database.Name);

                // récupération de la base de données déja parametrée dans _indexManager.InitialCatalog (si il y a...)
                if (!string.IsNullOrEmpty(_indexManager.InitialCatalog))
                    comboBoxInitialCatalog.SelectedItem = _indexManager.InitialCatalog;
            }
            catch (Exception)
            {
                MessageBox.Show("Error occurs during comboBoxInitialCatalog populating.");
            }
        }

        private ConnectionManager GetConnectioManager(Connections connections, string cmName)
        {
            ConnectionEnumerator connectionEnumerator = connections.GetEnumerator();
            while (connectionEnumerator.MoveNext())
            {
                ConnectionManager current = connectionEnumerator.Current;
                // lecture du code dans Reflector.
                if (current.Name == cmName)
                    return current;
            }
            return null;
        }

        private List<string> GetListADO_NETProviders(Connections connections)
        {
            var listAdoNetProviders = new List<string>();

            ConnectionEnumerator connectionEnumerator = connections.GetEnumerator();
            while (connectionEnumerator.MoveNext())
            {
                ConnectionManager current = connectionEnumerator.Current;
                // lecture du code dans Reflector dans la classe 
                if (current.CreationName.ToUpper().Contains("ADO.NET"))
                    listAdoNetProviders.Add(current.Name);
            }
            return listAdoNetProviders;
        }

        // méthode appelée à chaque fois que l'instance sélectionnée change
        void ComboBoxConnectionsSelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBoxConnections.SelectedItem != null)
            {
                // récupération d'un reference vers le "nouveau" ConnectionManager dont le nom est contenu dans comboBoxConnections
                var newConnectionManager = GetConnectioManager(_connectionsAdodotnet.GetConnections(), comboBoxConnections.SelectedItem.ToString());
                if (newConnectionManager != null)
                    InitComboInitialCatalog(newConnectionManager);
            }
        }
    }
}
